package com.jinrustar.httpfileserver.springboot;


import com.jinrustar.httpfileserver.core.HttpFileServerApp;
import com.jinrustar.httpfileserver.core.http.HttpFileServer;
import com.jinrustar.httpfileserver.core.ws.WSClient;
import com.jinrustar.httpfileserver.util.CommonUtil;
import com.jinrustar.httpfileserver.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import java.net.UnknownHostException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


@EnableTransactionManagement
@SpringBootApplication
@ComponentScan(basePackages = {"com.jinrustar.httpfileserver.springboot"})
@EnableRedisHttpSession /*开启redis集中式session管理*/
public class Application {

    public static final String FRONTEND_FILE_BROWSER_URL = "http://IP:5881/m-index"; /*前端页面地址*/

    protected final static Logger logger = LoggerFactory.getLogger(Application.class);

    private static boolean isHttpFileServerStarted = false;
    private static boolean isWebSocketServerStarted = false;
    private static boolean isApplicationStarted = false;


    public static WSClient wsClient = null; /*连接客户端用于发送消息到前端页面*/


    public static StartSuccessCallback startSuccessCallback = (ip, serviceTypeName) -> {
        if ("httpFileServer".equalsIgnoreCase(serviceTypeName)) {
            isHttpFileServerStarted = true;
            CommonUtil.notify("启动中。。。", "请稍候,httpFileServer已启动");
            try {
                String frontendFileBrowserUrl;
                frontendFileBrowserUrl = Application.FRONTEND_FILE_BROWSER_URL;
                frontendFileBrowserUrl = frontendFileBrowserUrl.replace("IP", ip);
                HttpFileServerApp.createQrCodeImgForFileBrowserUrl(frontendFileBrowserUrl, HttpFileServerApp.DIR + "youyubao_logo2.jpg", HttpFileServerApp.QR_IMG_PATH);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("##二维码生成失败，{}", e.getMessage());
            }
        } else if ("webSocketServer".equalsIgnoreCase(serviceTypeName)) {
            isWebSocketServerStarted = true;
            CommonUtil.notify("启动中。。。", "请稍候,webSocketServer已启动");

            /*HttpFileServer.wsClient = new WSClient(); *//*连接客户端用于发送消息到前端页面*/

        } else if ("application".equals(serviceTypeName)) { /*application*/
            isApplicationStarted = true;

            CommonUtil.notify("启动中。。。", "请稍候,application已启动");
        }

        onAllStarted();
    };

    private static void onAllStarted() {
        if (isHttpFileServerStarted && isWebSocketServerStarted) {
            if(!WSClient.isConnecting()){
                try {
                    new WSClient();
                } catch (Exception ex) {
                    logger.error("wsClient ");
                    ex.printStackTrace();
                    CommonUtil.notify("启动中。。。", " wsclient 出错");
                }
            }
        }

        if (isHttpFileServerStarted && isWebSocketServerStarted && isApplicationStarted) {
            try {
                CommonUtil.gotoUrl("http://localhost:5881");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    public static ExecutorService threadPool = Executors.newFixedThreadPool(3);

    public static void main(String[] args) throws Exception {

        getLocalIpWithBlock();

        CommonUtil.notify("启动中。。。", "请稍候");

        HttpFileServerApp.startHttpServerAndWebSocketServer(startSuccessCallback);

        threadPool.execute(() -> {
            CommonUtil.notify("启动中...", "请稍候,application启动中...");
            /*启动*/
            SpringApplication app = new SpringApplication(Application.class);
            app.setBannerMode(Banner.Mode.OFF);
            app.run(args);

            logger.debug("##application 已启动!");
            try {
                startSuccessCallback.onSuccess(HttpFileServer.IP, "application");
            } catch (Exception e) {
                e.printStackTrace();
            }

            isApplicationStarted = true;
            onAllStarted();
        });
    }


    public interface StartSuccessCallback {
        void onSuccess(String ip, String serviceTypeName) throws Exception;
    }


    private static int tryCount = 5;

    public static String getLocalIpWithBlock() throws UnknownHostException, InterruptedException {
        long delay = 500L;

        String localIp;
        while ((localIp = WebUtils.getLocalIP()).trim().length() == 0) {
            logger.debug("### 未获取到本地IP, 请检查网络, {}毫秒后重试", delay);
            if (tryCount-- >= 0) {
                CommonUtil.notify("未获取到本地IP, 请检查网络", "");
            }
            Thread.sleep(delay);
        }

        return localIp;
    }

}
